home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / tcclib.exe / MKWIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-07-18  |  5.4 KB  |  218 lines

  1. #include <conio.h>
  2. #include <alloc.h>
  3. #include <mem.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include "window.h"
  7. #include "_window.h"
  8.  
  9. windowtype *windowchain = NULL;
  10. static unsigned int xpos, ypos;
  11.  
  12. enum {TopLine, BottomLine, TopLeft, TopRight, BotLeft, BotRight,
  13.         RightLine, LeftLine } _box;
  14.  
  15. static unsigned char style[][8] =
  16.     {     { '-',    '-',    '+'   , '+'   , '+'   , '+'   , '|',    '|'    },
  17.         { '\xC4', '\xC4', '\xDA', '\xBF', '\xC0', '\xD9', '\xB3', '\xB3' },
  18.         { '\xCD', '\xCD', '\xC9', '\xBB', '\xC8', '\xBC', '\xBA', '\xBA' },
  19.         { '\xC4', '\xCD', '\xDA', '\xB7', '\xD4', '\xBC', '\xB3', '\xBA' }
  20.         };
  21.  
  22.  
  23. extern enum windowerrtype windowerr = WE_OK;
  24.  
  25. /* box() --------------------------------------------------------
  26.  *   Routine to draw a box around a window.
  27.  * --------------------------------------------------------------
  28.  */
  29. static void box(    unsigned char left,
  30.                     unsigned char top,
  31.                      unsigned char right,
  32.                     unsigned char bottom,
  33.                              char pattr,
  34.                     unsigned char *boxchars)
  35. {
  36.     unsigned int tmp1, tmp2, attr = pattr << 8;
  37.     int width, size, i;
  38.     unsigned int *box;
  39.  
  40.     if ( (box = malloc( (size = (right-left+1)*(bottom-top+1))*2 )) == NULL )
  41.         return;
  42.  
  43.     box[0] =  ' ' | attr;
  44.  
  45.     /* Ripple move the space with current attribute to the entire block */
  46.     /* This routine depends on memcpy not copying overlapping blocks
  47.      * correctly in the forward direction and two bytes at a time.
  48.      */
  49.     memcpy(&box[1],box,size<<1);
  50.  
  51.     /* Top line */
  52.     box[0] = boxchars[TopLeft] | attr;
  53.     box[ ((width = right - left + 1) - 1) ] = boxchars[TopRight] |
  54.         attr;
  55.  
  56.     box[1] = boxchars[TopLine] | attr;
  57.  
  58.     /* Ripple move - see above */
  59.     memcpy(&box[2],&box[1],(width-3)<<1);
  60.  
  61.     tmp1 = boxchars[LeftLine]  | attr;
  62.     tmp2 = boxchars[RightLine] | attr;
  63.     for (i = width; i<size-width; i += width)
  64.     {
  65.         box[i+width-1]     = tmp1;
  66.         box[i]             = tmp2;
  67.     }
  68.  
  69.     box[i] = boxchars[BotLeft] | attr;
  70.     box[i+width-1] = boxchars[BotRight] | attr;
  71.  
  72.     box[i+1] = boxchars[BottomLine] | attr;
  73.  
  74.     /* Ripple move - see above */
  75.     memcpy(&box[i+2],&box[i+1],(width-3)<<1);
  76.     puttext(left,top,right,bottom,box);
  77.  
  78.     free(box);
  79.  
  80. }
  81.  
  82. /* makewindow() ---------------------------------------------------
  83.  *   Open a window on the screen.  It becomes the current window.
  84.  *   RETURNS: 0 Success, 1 Out of memory, 2 Bad coordinates.
  85.  *   Coordinates must range from 2-79,2-24 (allow for the border).
  86.  *   Styles: 0 use not graphics chars, 1 single line, 2 double line
  87.  * ----------------------------------------------------------------
  88.  */
  89. windowtype *makewindow(    unsigned char  left,
  90.                            unsigned char  top,
  91.                            unsigned char  right,
  92.                         unsigned char  bottom,
  93.                         char            attr,
  94.                         unsigned char  the_style,
  95.                         char          *title)
  96. {
  97.     windowtype *current;
  98.     int size, len;
  99.  
  100.     windowerr = WE_OK;
  101.  
  102.     invalidate_backimage();
  103.  
  104.     /* Check the coordinates */
  105.     if (top < 2 || bottom > 24 || left < 2 || right > 79 || top > bottom
  106.         || left > right)
  107.     {
  108.         windowerr = WE_BADC;
  109.         return NULL;
  110.     }
  111.  
  112.     /* Allocate the memory for the window */
  113.     if ( (current = malloc(sizeof(windowtype))) == NULL )
  114.     {
  115.         windowerr = WE_OMEM;
  116.         return NULL;
  117.     }
  118.  
  119.     /* Store the coorinates (including the border) */
  120.     current->top    = --top;
  121.     current->bottom    = ++bottom;
  122.     current->left     = --left;
  123.     current->right    = ++right;
  124.  
  125.     /* Calculate the size of the back-buffer */
  126.     current->size = size = ((bottom-top+1)*(right-left+1)) << 1;
  127.  
  128.     /* Allocate the memory for the back buffer */
  129.     if ( (current->backbuffer = malloc(size)) == NULL )
  130.     {
  131.         windowerr = WE_OMEM;
  132.         return NULL;
  133.     }
  134.  
  135.     /* Store the cursor position for the current window */
  136.     if (windowchain)
  137.     {
  138.         windowchain->xpos = wherex();
  139.         windowchain->ypos = wherey();
  140.     }
  141.     else
  142.     {
  143.         xpos = wherex();
  144.         ypos = wherey();
  145.     }
  146.  
  147.     /* Store the screen image that we are going to write over */
  148.     gettext(left,top,right,bottom,current->backbuffer);
  149.  
  150.     /* Draw the border */
  151.     window(1,1,80,25);
  152.  
  153.     box(left,top,right,bottom,attr,style[the_style]);
  154.  
  155.     /* Set the writting attribute */
  156.     textattr(attr);
  157.     current->attr = attr;
  158.  
  159.     /* Center the title on the border */
  160.     /*  If the title is too big for the border or it
  161.      *  is empty, don't write it
  162.      */
  163.     if ( (len = strlen(title)) <= (right - left)   || len == 0 )
  164.     {
  165.         gotoxy( (right + left - len + 1) >> 1, top);
  166.         cputs(title);
  167.     }
  168.  
  169.     /* Section of the screen for the window */
  170.     window(left+1,top+1,right-1,bottom-1);
  171.  
  172.  
  173.     /* Register the window in the window chain, it becomes current */
  174.     if (windowchain != NULL)
  175.         windowchain->previous = current;
  176.     current->next = windowchain;
  177.     current->previous = NULL;
  178.     windowchain = current;
  179.  
  180.     /* Return the window */
  181.     return current;
  182. }
  183.  
  184. /* deletewindow() ----------------------------------------------
  185.  *    Delete a window.
  186.  *    RETURN: 0 Success, -1 Failure.
  187.  * -------------------------------------------------------------
  188.  */
  189. int deletewindow(windowtype *current)
  190. {
  191.     if (windowchain != current)
  192.         return -1;
  193.  
  194.     invalidate_backimage();
  195.  
  196.        puttext(current->left,current->top,current->right,current->bottom,
  197.         current->backbuffer);
  198.  
  199.     windowchain = current->next;
  200.     free(current->backbuffer);
  201.     free(current);
  202.     if (windowchain != NULL)
  203.         windowchain->previous = NULL;
  204.  
  205.     if (windowchain)
  206.     {
  207.         window(windowchain->left+1,windowchain->top+1,windowchain->right-1,
  208.                windowchain->bottom-1);
  209.         gotoxy(windowchain->xpos, windowchain->ypos);
  210.     }
  211.     else
  212.     {
  213.         window(1,1,80,25);
  214.         gotoxy(xpos,ypos);
  215.     }
  216.     return 0;
  217. }
  218.